﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YakShaver.Contract;
using YakShaver.TFSExtension;
using YakShaver.YakServer;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Server;
using System.Diagnostics;
namespace YakShaver.Tests.TFS
{
    /// <summary>
    /// Summary description for TFSServiceIntegrationTests
    /// </summary>
    [TestClass]
    public class TFSServiceIntegrationTests
    {
        public TFSServiceIntegrationTests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        private TeamFoundationServer tfsServer;
        private WorkItemStore tfsWorkItemStore;
        private Project currentProject;
        private string ProjectName = "YakShaver TFS";
        private ICommonStructureService commonStructureService;
        public const String Areas = "ProjectModelHierarchy";
        public const String Iterations = "ProjectLifecycle";

        private void SetupTeamServer(string serverName, ICredentialsProvider credentialsProvider)
        {
            TeamFoundationServer server = TeamFoundationServerFactory.GetServer(serverName, credentialsProvider);
            server.Authenticate();

            tfsWorkItemStore = (WorkItemStore)server.GetService(typeof(WorkItemStore));
            commonStructureService = (ICommonStructureService)server.GetService(typeof(ICommonStructureService));

            //artifactProvider
            Project project = tfsWorkItemStore.Projects[ProjectName];
            currentProject = project;

        }
        private string CreateIteration()
        {
            string iterationName = "Iteration - IT - " + DateTime.Now.ToString("yyyy-MM-dd hh_mm_ss");
            NodeInfo iterationNode = GetCssStructure(commonStructureService, currentProject.Uri.ToString(), Iterations);

            string newIterationUri = commonStructureService.CreateNode(iterationName, iterationNode.Uri);
            NodeInfo newNode = commonStructureService.GetNode(newIterationUri);
            return newNode.Name;

        }
        private string CreateArea()
        {
            //Node areaNode = new Node();
            string areaName = "Area - IT - " + DateTime.Now.ToString("yyyy-MM-dd hh_mm_ss");
            NodeInfo areaNode = GetCssStructure(commonStructureService, currentProject.Uri.ToString(), Areas);


            string newAreaName = commonStructureService.CreateNode(areaName, areaNode.Uri);
            NodeInfo newNode = commonStructureService.GetNode(newAreaName);
            return newNode.Name;
            //return currentProject.AreaRootNodes[newAreaName].Id.ToString();
        }


        // Thanks Brian Harry!
        // http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=406877&SiteID=1
        public static NodeInfo GetCssStructure(ICommonStructureService css, String projectUri, String structureType)
        {
            NodeInfo[] nodes = css.ListStructures(projectUri);
            foreach (NodeInfo node in nodes)
            {
                if (node.StructureType == structureType)
                {
                    return node;
                }
            }
            return null;
        }

        [TestMethod, TestProperty("Category", "TFS\\Integration")]
        public void TestTFSCreateWorkItem()
        {
            TFSWorkItemService service = new TFSWorkItemService();
            SetupTeamServer("TFSRTM08", new DummyObjects.ArchitechtCredentialProvider());
            string area = CreateArea();
            string iteration = CreateIteration();

            // having problems with it not finding the area.. so instead of making this part of the 
            // actual service class, have the test class ensure that the cache is resynced and it can grab the
            // area.  I don't know if this has something to do with using a virtual machine or not (I would doubt
            // so, but I could be wrong)

            //  System.Threading.Thread.Sleep(1000); 
            //   tfsWorkItemStore.RefreshCache();
            //tfsWorkItemStore.SyncToCache();
            bool areaFound = false;
            while (!areaFound)
            {
                try
                {
                    System.Threading.Thread.Sleep(3000);
                    tfsWorkItemStore.RefreshCache();
                    string tempArea = tfsWorkItemStore.Projects[currentProject.Name].AreaRootNodes[area].Path;
                    areaFound = true; // iif it isn't found an exception is thrown never getting to this.

                }
                catch (Exception ex)
                {
                    areaFound = false;
                }
            }

            bool iterationFound = false;

            while (!iterationFound)
            {
                try
                {
                    System.Threading.Thread.Sleep(3000);
                    tfsWorkItemStore.RefreshCache();
                    string tempIteration = tfsWorkItemStore.Projects[currentProject.Name].IterationRootNodes[iteration].Path;
                    iterationFound = true;
                }
                catch (Exception ex)
                {
                    iterationFound = false;
                }
            }


            currentProject = tfsWorkItemStore.Projects[currentProject.Name];

            service.CredentialsProvider = new DummyObjects.ArchitechtCredentialProvider();
            service.ServerName = "TFSRTM08";
            service.TfsProject = currentProject;

            YakShaverWorkItem workItem = new YakShaverWorkItem();
            workItem.Component = area;
            workItem.Release = iteration;
            workItem.Description = "Test Description";
            workItem.WorkItemType = YakShaver.Contract.WorkItemType.Task;
            workItem.WorkItemImpactType = WorkItemImpactType.Medium;
            workItem.Title = "Test title - " + this.GetHashCode();
            service.CreateWorkItem(workItem);

            Assert.IsTrue(workItem.WorkItemId != string.Empty);

            foreach (NodeInfo node in commonStructureService.ListStructures(currentProject.Uri.ToString()))
            {
                Debug.WriteLine("Node: " + node.Name + " URI:" + node.Uri + " Parent URI: " + node.ParentUri + " Path:" + node.Path + " Structure Type: " + node.StructureType);
                Debug.Indent();
                foreach (Property prop in node.Properties)
                {

                    Debug.WriteLine("Property Name: " + prop.Name + " Property Value:" + prop.Value);

                }
                Debug.Unindent();
                // Debug.WriteLine("Node: " +  node.Name + " Area Node: " + node.IsAreaNode.ToString() + " Path: " + node.Path + " URI: " + node.Uri.ToString());
                Debug.WriteLine("----------------------------------");
            }


        }
        [TestMethod, TestProperty("Category", "TFS\\Integration")]
        public void TestTFSAnalysisNeedIntervention()
        {

        }
        [TestMethod, TestProperty("Category", "TFS\\Integration")]
        public void TestTFSAnalysisNoInterventionNeeded()
        {

        }
    }
}